#!/usr/bin/python
# coding:utf-8
__author__ = 'good'
__createday__ = '2015-01-14'

from datetime import datetime

from ..extensions import db
from config import ARTICLES_PER_PAGE
from sqlalchemy.orm.collections import attribute_mapped_collection

IS_USE = 1


class Article(db.Model):
    """文章"""
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), index=True, nullable=False)
    body = db.Column(db.Text, nullable=False)
    text = db.Column(db.String(4000), nullable=False)
    tag = db.Column(db.String(50), nullable=False)
    post_date = db.Column(db.DateTime, nullable=False)
    is_open = db.Column(db.Boolean, nullable=False)
    timestamp = db.Column(db.DateTime, default=datetime.utcnow(), nullable=False)
    months = db.Column(db.String(7), default=str(datetime.now())[:7])
    numlook = db.Column(db.Integer)
    # ：外键
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'), nullable=False)
    # ：关系
    upload_file = db.relationship('Uploads', backref='article', lazy='dynamic')
    comment = db.relationship('Comments', backref='article', lazy='dynamic')

    def __init__(self, title, body, text, timestamp, user_id, category_id, tag, is_open, numLook=0):
        self.title = title
        self.body = body
        self.text = text
        self.timestamp = timestamp
        self.user_id = user_id
        self.category_id = category_id
        self.tag = tag
        self.is_open = is_open
        self.numlook = numLook

    def __repr__(self):
        return '<Article %r>' % (self.title)

    # 根据ID
    @classmethod
    def find_by_id(self, max_id):
        art = self.query.filter_by(id=max_id).first_or_404()
        return art

    # 分类、分月查询
    @classmethod
    def article_per_page(cls, name, month, page=1):
        if name == 'all' and month == 'all':
            art = Article.query.filter_by(is_open=1).order_by(Article.timestamp.desc())
            return art.paginate(page, ARTICLES_PER_PAGE, False)
        elif month == 'all' and name <> 'all':
            cg = Category.find_by_name(name)
            art = Article.query.filter(Article.category_id == cg.id, Article.is_open == 1).order_by(
                Article.timestamp.desc())
            return art.paginate(page, ARTICLES_PER_PAGE, False)
        elif month <> 'all' and name == 'all':
            art = Article.query.filter(Article.months == month, Article.is_open == 1).order_by(Article.timestamp.desc())
            if art is not None:
                return art.paginate(page, ARTICLES_PER_PAGE, False)
        elif month <> 'all' and name <> 'all':
            cg = Category.find_by_name(name)
            art = Article.query.filter(Article.months == month, Article.category_id == cg.id,
                                       Article.is_open == 1).order_by(
                Article.timestamp.desc())
            return art.paginate(page, ARTICLES_PER_PAGE, False)
        else:
            return None

    # 所有博文，最后编辑时间倒序
    @classmethod
    def article_all(cls):
        art = Article.query.order_by(Article.timestamp.desc())
        return art

    # 按月统计
    @classmethod
    def count_by_month(cls):
        month_count = db.session.query(Article.months, db.func.count('*').label('num')).group_by(
            Article.months).order_by(Article.months.desc())
        return month_count

    # 当月博文统计
    @classmethod
    def count_current_month(cls):
        current_month = str(datetime.now())[:7]
        count = db.session.query(Article.months, db.func.count('*').label('num')).filter(
            Article.months == current_month).first().num
        return count

    # ：搜索
    @classmethod
    def search(cls, st, page=1, num=ARTICLES_PER_PAGE):
        from sqlalchemy.sql import or_

        if st is None:
            article = Article.query.filter().order_by(Article.timestamp.desc())
        else:
            article = Article.query.filter(
                or_(Article.title.like('%' + st + '%'), Article.body.like('%' + st + '%'))).order_by(
                Article.timestamp.desc())
        return article.paginate(page, num, False)

    # 是否再次经过编辑
    @classmethod
    def find_edit(cls, start, stop):
        article = Article.query.filter(Article.is_open == 1,
                                       Article.post_date <> Article.timestamp).filter(
            Article.timestamp >= start).filter(Article.timestamp <= stop).all()
        return article

    # 统计所有博文数量
    @classmethod
    def count_all(cls):
        count = db.session.query(db.func.count(Article.id).label('article_count')).first().article_count
        return count

    # 按类别统计博文数量
    @classmethod
    def count_by_category(cls):
        art = db.session.query(Category.name,
                               db.func.count(Article.id).label('count')).filter(
            Category.id == Article.category_id).group_by(Category.name).all()
        return art

    # top
    @classmethod
    def top(cls, num):
        art = db.session.query(Article).order_by(Article.numlook.desc()).limit(num)
        return art


class Category(db.Model):
    """文章类别"""
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), index=True)
    createdate = db.Column(db.DateTime)
    article = db.relationship('Article', backref='category', lazy='dynamic')
    is_use = db.Column(db.Boolean, default=True)
    seq = db.Column(db.Integer)

    def __repr__(self):
        return '<Category %r>' % (self.name)

    @classmethod
    def find_by_name(cls, name):
        return Category.query.filter(Category.name == name, Category.is_use == 1).first_or_404()

    @classmethod
    def default_seq(cls):
        return db.session.query(db.func.max(Category.seq).label('seq_max')).first().seq_max + 1

    @classmethod
    def choices(cls):
        choice = [(c.id, c.name) for c in
                  Category.query.filter_by(is_use=1).order_by(Category.seq)]
        return choice


class Uploads(db.Model):
    """文章附件"""
    __tablename__ = 'uploads'
    id = db.Column(db.Integer, primary_key=True)
    file_name = db.Column(db.String(50))
    file_url = db.Column(db.String(50))
    file_type = db.Column(db.String(4))
    upload_date = db.Column(db.DateTime)
    upload_user = db.Column(db.Integer)
    article_id = db.Column(db.Integer, db.ForeignKey('article.id'), nullable=False)

    @classmethod
    def get_imgs(cls):
        imgs = Uploads.query.filter_by(file_type='img').order_by(Uploads.upload_date.desc())
        return imgs

    @classmethod
    def get_atts(cls):
        atts = Uploads.query.filter_by(file_type='att').order_by(Uploads.upload_date.desc())
        return atts


class Comments(db.Model):
    """评论"""
    __tablename__ = 'comments'
    id = db.Column(db.INTEGER, primary_key=True)
    name = db.Column(db.String(50))
    comment = db.Column(db.Text)
    has_comment = db.Column(db.INTEGER, default=0)
    disable = db.Column(db.Integer, default=0)  # 0 未审核，1 通过，2 未通过
    timestamp = db.Column(db.DateTime, default=datetime.utcnow())
    article_id = db.Column(db.Integer, db.ForeignKey('article.id'), default=0)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    parent_id = db.Column(db.Integer, db.ForeignKey('comments.id'))
    children = db.relationship("Comments", cascade="all",
                               backref='parent', remote_side=[id],
                               collection_class=attribute_mapped_collection('name'))

    def __repr__(self):
        return '<Comment(id:%s,parent_id:%s>' % (self.id, self.parent_id)

    @classmethod
    def count_all(cls):
        num = cls.query.filter().count()
        return num

    def dump(self, _indent=0):
        return " " * _indent + repr(self) + \
               "\n" + \
               "".join([c.dump(_indent + 1) for c in self.parent.values()])

    @classmethod
    def count_month(cls):
        month = datetime.now().strftime('%Y-%m')
        num = cls.query.filter(cls.timestamp.like('%' + month + '%')).count()
        return num

    @classmethod
    def ten_newest(cls, num=10):
        ten = cls.query.filter(cls.disable == 1).order_by(cls.timestamp.desc()).limit(num).all()
        return ten

    @classmethod
    def get_child(cls, parent):
        child = cls.query.filter_by(parent_id=parent.id, disable=1).all()
        if len(child) > 0:
            tmp = []
            for c in child:
                # return cls.get_comment(c.id)
                # mp.append(c)
                tmp.append(cls.get_child(c))
            return [parent, tmp]
        else:
            return [parent]

    @staticmethod
    def get_comment(article_id=None):
        result = list()
        comm = Comments.query.filter(Comments.article_id == article_id,
                                     Comments.disable == 1).all()
        for c in comm:
            result.append(
                Comments.get_child(c))
        return result
